﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BusinessLogic.Connectivity.Entities;
using BankApplication.BusinessLogic;
using System.Xml.Serialization;
using System.IO;
using BusinessLogic.BusinessEntity.Entities;
using BusinessLogic.Cryptography;
using System.ServiceModel;


namespace BankApplication.UI
{
	public enum UserFormType
	{
		CREATE_USER,
		UPDATE_USER
	}

	public partial class UserForm : Form
	{
		public UserForm()
		{
			InitializeComponent();

			User = new User();
		}

		public UserForm(User user, UserFormType dialogType) : this()
		{
			nameTextBox.Text = user.Name;
			emailTextBox.Text = user.Email;
			faxTextBox.Text = user.Fax;
			middleNameTextBox.Text = user.MiddleName;
			phoneTextBox.Text = user.Phone;
			surnameTextBox.Text = user.Surname;

			Credentials credentials = new Credentials();
			credentials.Login = loginTextBox.Text;
			credentials.Password = passwordTextBox.Text;

			loginTextBox.Text = user.Login;
			passwordTextBox.Text = user.Password;
			repeatPasswordTextBox.Text = user.Password;

			userFormType = dialogType;
			this.user = user;
		}


		public User User { get; private set; }


		private void ValidateForm()
		{
			if (nameTextBox.Text == string.Empty)
			{
				throw new ValidationException("'Name' field cannot be empty!");
			}


			if (!ValidationHelper.IsAlphabetical(nameTextBox.Text))
			{
				throw new ValidationException("'Name' field must contain only the letters of the English alphabet!");
			}


			if (surnameTextBox.Text == string.Empty)
			{
				throw new ValidationException("'Surname' field cannot be empty!");
			}

			if (!ValidationHelper.IsAlphabetical(surnameTextBox.Text))
			{
				throw new ValidationException("'Surname' field must contain only the letters of the English alphabet!");
			}


			if (middleNameTextBox.Text == string.Empty)
			{
				throw new ValidationException("'Middle name' field cannot be empty!");
			}

			if (!ValidationHelper.IsAlphabetical(middleNameTextBox.Text))
			{
				throw new ValidationException("'Middle name' field must contain only the letters of the english alphabet!");
			}


			if (emailTextBox.Text == string.Empty)
			{
				throw new ValidationException("'Email' field cannot be empty!");
			}

			if (!ValidationHelper.IsValidEmail(emailTextBox.Text))
			{
				throw new ValidationException("Wrong email format! Specify a valid email e.g. support@leciel.com");
			}

			
			if (phoneTextBox.Text == string.Empty)
			{
				throw new ValidationException("'Phone' field cannot be empty!");
			}

			if (!ValidationHelper.IsValidPhoneNumber(phoneTextBox.Text))
			{
				throw new ValidationException("Invalid phone number! It must consist of the digits 0-9 and can start with a '+' sign.");
			}


			if (faxTextBox.Text == string.Empty)
			{
				throw new ValidationException("'Fax' field cannot be empty!");
			}

			if (!ValidationHelper.IsValidPhoneNumber(faxTextBox.Text))
			{
				throw new ValidationException("Invalid fax! It must consist of the digits 0-9 and can start with a '+' sign.");
			}
			

			// Credentials validation

			if (loginTextBox.Text == string.Empty)
			{
				throw new ValidationException("'Login' field cannot be empty!");
			}

			if (passwordTextBox.Text == string.Empty)
			{
				throw new ValidationException("'Password' field cannot be empty!");
			}

			if (repeatPasswordTextBox.Text == string.Empty)
			{
				throw new ValidationException("'Repeat password' field cannot be empty!");
			}

			if (!passwordTextBox.Text.Equals(repeatPasswordTextBox.Text))
			{
				throw new ValidationException("Passwords do not match!");
			}
		}


		private void CreateUser()
		{

			try
			{
				ValidateForm();

				var newUser = new User();

				newUser.Name = nameTextBox.Text;
				newUser.Email = emailTextBox.Text;
				newUser.Fax = faxTextBox.Text;
				newUser.MiddleName = middleNameTextBox.Text;
				newUser.Phone = phoneTextBox.Text;
				newUser.Surname = surnameTextBox.Text;
				newUser.Login = loginTextBox.Text;
				newUser.Password = passwordTextBox.Text;

				RSAKeys keysPair = RSADigitalSignatureManager.GenerateRSAKeys();
				newUser.PublicKey = keysPair.PublicKey;

				Credentials credentials = new Credentials();
				credentials.Login = loginTextBox.Text;
				credentials.Password = passwordTextBox.Text;

				MiscUtils.SerializeToXML(keysPair.PrivateKey, MiscUtils.GetSaveFileName("Save private key to ..."));
				MiscUtils.SerializeToXML(credentials, MiscUtils.GetSaveFileName("Save credentials to ..."));

				new ServerInteractionExceptionCatcher().Execute(() =>
				{
					UsersManager.CreateUser(newUser, SessionManager.Instance.SessionTicket);

					this.Close();
				});				
			}
			catch (ValidationException exception)
			{
				MessageBox.Show(exception.Message, "Form validation failed!", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			catch (NoFileNameSpecifiedException)
			{
				MessageBox.Show("No file name has been specified!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
			catch (IOException)
			{
				MessageBox.Show("File operation failed!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			catch (Exception)
			{
				MessageBox.Show("Unknown error has been encountered! Terminating...", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				Application.Exit();
			}
		}

		private void UpdateUser()
		{
			try
			{
				ValidateForm();

				user.Name = nameTextBox.Text;
				user.Email = emailTextBox.Text;
				user.Fax = faxTextBox.Text;
				user.MiddleName = middleNameTextBox.Text;
				user.Phone = phoneTextBox.Text;
				user.Surname = surnameTextBox.Text;
				
				if (user.Login != loginTextBox.Text || user.Password != passwordTextBox.Text)
				{
					user.Login = loginTextBox.Text;
					user.Password = passwordTextBox.Text;

					Credentials credentials = new Credentials();
					credentials.Login = loginTextBox.Text;
					credentials.Password = passwordTextBox.Text;

					MiscUtils.SerializeToXML(credentials, MiscUtils.GetSaveFileName("Save credentials to ..."));
				}

				new ServerInteractionExceptionCatcher().Execute(() =>
				{
					UsersManager.UpdateUser(user, SessionManager.Instance.SessionTicket);

					this.Close();
				});
			}
			catch (ValidationException exception)
			{
				MessageBox.Show(exception.Message, "Form validation failed!", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			catch (NoFileNameSpecifiedException)
			{
				MessageBox.Show("No file name has been specified!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
			catch (IOException)
			{
				MessageBox.Show("File operation failed!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			catch (Exception)
			{
				MessageBox.Show("Unknown error has been encountered! Terminating...", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				Application.Exit();
			}
		}
		

		private void SaveButton_Click(object sender, EventArgs e)
		{
			if (userFormType == UserFormType.UPDATE_USER)
			{
				UpdateUser();
			}
			else
			{
				CreateUser();
			}
		}

		private void CloseButton_Click(object sender, EventArgs e)
		{
			this.Close();
		}


		private UserFormType userFormType = UserFormType.CREATE_USER;
		private User user;
	}
}
